Respository裡面放的是資料庫邏輯。
如果在比較大型的專案,會把Repository跟Entity拆開,讓資料庫操作的動作能夠跟設定分開,會比較易於維護。
<?php
namespace App\Repositories;
use App\Entities\Product;
use Illuminate\Database\Eloquent\Model;
class ProductRepository extends Model
{
protected $product;
public function __construct()
{
$this->product = new Product();
}
public function get()
{
return $this->product
->get();
}
}
class ProductRepository extends Model
{
protected $product;
public function __construct()
{
$this->product = Product::query();
}
public function get()
{
return $this->product
->get();
}
public function filterByName($name)
{
$this->product->where('name', $name);
return $this; //記得這個this 要另外寫,不然回傳的東西會不一樣
}
}
用基本範例
跟query builder範例
兩個因為在回傳值上面不同,所以其實用法也不太一樣,如果只是在普通的CRUD上面,兩者的做法是差不多的,但是query builder 更多了一些彈性。
舉個例子,在實作後台時常常會有需求要多重搜尋,這時候如果用基本範例,就很難達到,不然就是重複的內容可能要寫很多次然後用疊加的,有可能會想這樣寫
public function getWithId($id)
{
return $this->product
->where('id', $id)
->get();
}
public function getWithIdAndName($id, $name)
{
return $this->product
->where('id', $id)
->where('name', $name)
->get();
}
又或者可能就會想要直接把where條件寫在Controller或是Service,但是這樣就失去我們分工的意義了,如果這時候是用query的話,一樣會有兩個function,但是之後在Service卻能彈性被使用[之後Service篇也會有範例]
如果用query builder寫
public function filterById($id)
{
$this->product->where('id', $id);
return $this;
}
public function filterByName($name)
{
$this->product->where('name', $name);
return $this;
}
如果有興趣把上面兩個dump出來的話會更明顯
$this->product = new Product();
object(App\Entities\Product)#189 (26) {
["table":protected]=>
string(8) "products"
.....
$this->product = Product::query();
object(Illuminate\Database\Eloquent\Builder)#196 (8) {
["query":protected]=>
object(Illuminate\Database\Query\Builder)#195 (22) {
["connection"]=>
object(Illuminate\Database\MySqlConnection)#191 (17) {
["pdo":protected]=>
object(Closure)#190 (2) {
.....
正因為return的是query builder 才有辦法這樣彈性的銜接。
如果有興趣了解更多的話,有一個小活動大家可以試試看,就是把return $this;
跟直接return;
配合上面兩種宣告排列組合印出來看,相信會有更深入的認識。
結論: query builder的範例使用部分一般比較少提到,這邊可以注意到query builder & 一般使用上不同的方式。